import { Injectable } from '@angular/core';
import {
  setCurrentAction,
  setCurrentIndex,
  setPlayList,
  setPlayMode,
  setSongList
} from '@store/actions/player.actions';
import {
  setModalVisible,
  setModalType,
  setUserId,
  setLikedId,
  setShareInfo
} from '@store/actions/member.actions';
import { Song } from '@services/data-types/common.type';
import { findIndex, shuffle } from '@utils/array';
import { select, Store } from '@ngrx/store';
import { AppStoreModule } from '@store/index';
import { PlayState } from '@store/reducers/player.reducer';
import { getPlayer } from '@store/selectors/player.selector';
import { MemberState, ModalTypes, ShareInfo } from '@store/reducers/member.reducer';
import { getMember } from '@store/selectors/member.selector';
import { PlayMode } from '@share/wyy-ui/wyy-player/player-types';
import { CurrentActions } from '@store/reducers/player.reducer';

const modeTypes: PlayMode[] = [
  {
    type: 'loop',
    label: '循环'
  },
  {
    type: 'random',
    label: '随机'
  },
  {
    type: 'singleLoop',
    label: '单曲循环'
  }
];


@Injectable({
  providedIn: AppStoreModule
})
export class BatchActionsService {
  private playerState: PlayState;
  private memberState: MemberState;
  constructor(private store$: Store<AppStoreModule>) {
    this.store$.pipe(select(getPlayer)).subscribe((res: PlayState) => this.playerState = res);
    this.store$.pipe(select(getMember)).subscribe((res: MemberState) => this.memberState = res);
  }
  // 添加歌单列表
  selectPlayList({list, index}: {list: Song[], index: number}) {
    let realIndex = index;
    let realList = list.slice();
    // 获取歌单数据之前就已经是随机模式，要对playList和currentIndex做处理
    if (this.playerState.playMode.type === 'random') {
      realIndex = findIndex(realList, list[realIndex]);
      realList = shuffle(list || []);
    }
    this.store$.dispatch(setSongList({ songList: list }));
    this.store$.dispatch(setPlayList({ playList: realList }));
    this.store$.dispatch(setCurrentIndex({ currentIndex: realIndex }));
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Play }));
  }
  // 播放模式切换
  onToggleMode(modeCount) {
    this.store$.dispatch(setPlayMode({ playMode: modeTypes[modeCount] }));
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Other }));
  }
  // 清空一首歌曲
  onDeleteSong(song: Song) {
    const songList = this.playerState.songList.slice();
    const playList = this.playerState.playList.slice();
    let currentIndex = this.playerState.currentIndex;
    const sIndex = findIndex(songList, song);
    const pIndex = findIndex(playList, song);
    songList.splice(sIndex, 1);
    playList.splice(pIndex, 1);
    if (currentIndex > pIndex || currentIndex === playList.length) {
      currentIndex--;
    }
    this.store$.dispatch(setCurrentIndex({ currentIndex }));
    this.store$.dispatch(setPlayList({ playList }));
    this.store$.dispatch(setSongList({ songList }));
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Delete }));
  }
  // 清空全部歌曲
  onClearSong() {
    this.store$.dispatch(setCurrentIndex({ currentIndex: -1 }));
    this.store$.dispatch(setPlayList({ playList: [] }));
    this.store$.dispatch(setSongList({ songList: [] }));
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Clear }));
  }
  // 不同播放模式下的歌曲列表和播放列表
  onPlayModePlayList(list: Song[]) {
    this.store$.dispatch(setPlayList({ playList: list }));
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Play }));
  }
  // 更新当前播放的歌曲索引
  updateSongIndex(index: number) {
    this.store$.dispatch(setCurrentIndex({ currentIndex: index }));
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Other }));
  }
  // 添加一首歌曲
  insertSong(song: Song, isPlay: boolean) {
    const songList = this.playerState.songList.slice();
    let playList = this.playerState.playList.slice();
    let insertIndex = this.playerState.currentIndex;
    const pIndex = findIndex(playList, song);
    if (pIndex > -1) {
      if (isPlay) {
        insertIndex = pIndex;
      }
    } else {
      songList.push(song);
      if (isPlay) {
        insertIndex = playList.length;
      }
      if (this.playerState.playMode.type === 'random') {
        playList = shuffle(songList);
      } else {
        playList.push(song);
      }
      this.store$.dispatch(setPlayList({ playList }));
      this.store$.dispatch(setSongList({ songList }));
    }
    if (insertIndex !== this.playerState.currentIndex) {
      this.store$.dispatch(setCurrentIndex({ currentIndex: insertIndex }));
      this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Play }));
    } else {
      this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Add }));
    }
  }
  // 添加歌曲列表
  insertSongList(songs: Song[]) {
    let songList = this.playerState.songList.slice();
    let playList = this.playerState.playList.slice();
    // 歌曲列表/播放列表是否已存在
    if (!songList.length || !playList.length) {
      this.store$.dispatch(setSongList({ songList: songs }));
      if (this.playerState.playMode.type === 'random') {
        const songPlayList = shuffle(songList);
        this.store$.dispatch(setPlayList({ playList: songPlayList }));
      } else {
        this.store$.dispatch(setPlayList({ playList: songs }));
      }
    } else {
      const validSongs = songs.filter(song => findIndex(playList, song) === -1);
      if (validSongs.length) {
        songList = songList.concat(validSongs);
        let songPlayList = validSongs.slice();
        if (this.playerState.playMode.type === 'random') {
          songPlayList = shuffle(songList);
        }
        playList = playList.concat(songPlayList);
        this.store$.dispatch(setPlayList({ playList }));
        this.store$.dispatch(setSongList({ songList }));
      }
    }
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Add }));
  }
  // 监听Actions的变化
  watchActions() {
    this.store$.dispatch(setCurrentAction({ currentAction: CurrentActions.Other }));
  }
  // 弹窗状态/类型
  controlModalVisible(modalVisible = true, modalType?: string) {
    if (modalType) {
      this.store$.dispatch(setModalType({ modalType }));
    }
    this.store$.dispatch(setModalVisible({ modalVisible }));
  }
  changeModalType(type: string) {
    this.store$.dispatch(setModalType({ modalType: type }));
  }
  likeSong(id: string) {
    this.store$.dispatch(setModalType({ modalType: ModalTypes.Like }));
    this.store$.dispatch(setLikedId({ likedId: id }));
  }
  setUserId(id: string) {
    this.store$.dispatch(setUserId({ userId: id }));
  }
  setShareInfo(info: ShareInfo) {
    this.store$.dispatch(setShareInfo({ shareInfo: info }));
  }
}
